﻿namespace AgentJohnson.CodeAnnotations
{
  using AgentJohnson.DocumentThrownExceptions;
  using JetBrains.Annotations;
  using Resharper.Abstractions.CodeAnnotations;
  using Resharper.Abstractions.CodeDom.TreeNodes;
  using Resharper.Abstractions.CodeDom.TypeMembers.Constructors;
  using Resharper.Abstractions.CodeDom.TypeMembers.Indexers;
  using Resharper.Abstractions.CodeDom.TypeMembers.Methods;
  using Resharper.Abstractions.CodeDom.TypeMembers.Properties;
  using Resharper.Abstractions.Daemons;

  /// <summary>Defines the <see cref="DocumentThrownExceptionDaemon"/> class.</summary>
  [DaemonStage]
  public class CodeAnnotationDaemon : CodeAnnotationDaemonBase
  {
    #region Methods

    /// <summary>Processes the specified tree node.</summary>
    /// <param name="treeNode">The tree node.</param>
    protected override void Process([NotNull] TreeNode treeNode)
    {
      CodeAnnotationModel model = null;

      Property property = null;
      Constructor constructor = null;
      Indexer indexer = null;

      var method = treeNode.GetMethod();
      if (method != null)
      {
        model = new CodeAnnotationModel();
        model.Inspect(method);
      }

      if (model == null)
      {
        property = treeNode.GetProperty();
        if (property != null)
        {
          model = new CodeAnnotationModel();
          model.Inspect(property);
        }
      }

      if (model == null)
      {
        constructor = treeNode.GetConstructor();
        if (constructor != null)
        {
          model = new CodeAnnotationModel();
          model.Inspect(constructor);
        }
      }

      if (model == null)
      {
        indexer = treeNode.GetIndexer();
        if (indexer != null)
        {
          model = new CodeAnnotationModel();
          model.Inspect(indexer);
        }
      }

      if (model == null || model.IsAnnotated)
      {
        return;
      }

      var highlight = this.CreateHighlight<CodeAnnotationHighlight>();
      highlight.Model = model;

      if (method != null)
      {
        highlight.Range = method.GetRange();
      }
      else if (property != null)
      {
        highlight.Range = property.GetRange();
      }
      else if (constructor != null)
      {
        highlight.Range = constructor.GetRange();
      }
      else 
      {
        highlight.Range = indexer.GetRange();
      }
    }

    #endregion
  }
}